<!DOCTYPE HTML>
<html>

<head>
    <meta charset="UTF-8">
    <title>Cube Robot Debug</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="data:,">
    <style>
        html {
            font-family: 'Arial', sans-serif;
            text-align: center;
            background-color: #f0f0f0;
        }

        h2 {
            font-size: 1.5rem;
            font-weight: bold;
            color: #07156d;
            margin-top: 0;
        }

        h3 {
            font-size: 1.3rem;
            color: #07156d;
            margin: 15px 0;
        }

        .card {
            background-color: #FFFFFF;
            box-shadow: 2px 2px 12px 1px rgba(140, 140, 140, .5);
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        body {
            margin: 0;
            padding: 0;
        }

        .content {
            padding: 15px;
            max-width: 900px;
            margin: 0 auto;
        }

        .button {
            padding: 15px 50px;
            font-size: 24px;
            text-align: center;
            outline: none;
            color: #fff;
            background-color: #0ffa6d;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.2s;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
            display: block;
            width: 100%;
            max-width: 300px;
            margin: 0 auto 20px;
            box-sizing: border-box;
        }

        .button:active {
            background-color: #0bd45a;
            transform: translateY(2px);
        }

        .state {
            font-size: 1.5rem;
            color: #120707;
            font-weight: bold;
            margin: 15px 0;
        }
        
        .slider {
            width: 100%;
            max-width: 400px;
            height: 25px;
            margin: 15px auto;
            display: block;
        }
        
        .video-container {
            width: 100%;
            max-width: 640px;
            margin: 0 auto;
            background-color: #000;
            border-radius: 8px;
            overflow: hidden;
            position: relative;
            aspect-ratio: 4/3;
        }
        
        #videoStream {
            width: 100%;
            height: 100%;
            object-fit: contain;
            display: block;
        }
        
        .status-overlay {
            position: absolute;
            bottom: 10px;
            right: 10px;
            background: rgba(0,0,0,0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 0.8rem;
            transition: opacity 0.5s ease;
            z-index: 1; /* 确保状态提示在覆盖层之上 */
        }
        
        .status-overlay.hidden {
            opacity: 0;
        }
        
        #overlayCanvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: auto; /* 改为auto以接收鼠标事件 */
            z-index: 2; /* 确保覆盖层在状态提示之下 */

        }
        
        .two-column {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            justify-content: center;
        }
        
        .column {
            flex: 1;
            min-width: 300px;
        }
        
        .cube-layout {
            display: grid;
            grid-template-columns: repeat(12, 1fr);
            grid-template-rows: repeat(9, 1fr);
            gap: 1px;
            width: 100%;
            max-width: 600px;
            margin: 20px auto;
            background-color: #ddd;
            border: 1px solid #ccc;
        }
        
        .cube-cell {
            aspect-ratio: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 0.7rem;
            font-weight: bold;
            position: relative;
            background-color: #fff;
        }
        
        .cube-cell.hidden {
            visibility: hidden;
        }
        
        .cube-cell .index {
            position: absolute;
            top: 2px;
            left: 2px;
            font-size: 0.6rem;
            color: rgba(0,0,0,0.7);
        }
        
        .debug-button {
            padding: 8px 15px;
            background-color: #e0e0e0;
            border: 1px solid #ccc;
            border-radius: 4px;
            cursor: pointer;
            margin: 5px;
        }
        
        .debug-button:hover {
            background-color: #d0d0d0;
        }
        
        .coordinates {
            font-family: monospace;
            font-size: 0.9rem;
            background-color: #f0f0f0;
            padding: 5px;
            border-radius: 4px;
            margin: 10px 0;
        }
        
        .button-container {
            display: flex;
            justify-content: center;
            flex-wrap: wrap;
            margin-top: 10px;
        }
        
        @media (max-width: 650px) {
            .two-column {
                flex-direction: column;
            }
            
            .cube-layout {
                transform: scale(0.9);
                transform-origin: center;
            }
        }
    </style>
</head>

<body>
    <div class="content">
        <div class="two-column">
            <div class="column">
                <div class="card">
                    <h2>控制面板</h2>
                    <button id="button" class="button">开始还原</button>
                    <p class="state">补光灯亮度：<span id="brightnessValue">25</span>%</p>
                    <input type="range" min="0" max="100" value="25" class="slider" id="brightnessSlider">
                    
                    <h3>标记点位置</h3>
                    <div id="coordinatesDisplay" class="coordinates">(80,60), (160,60), (240,60), (80,180), (160,180), (240,180)</div>
                    <button id="resetPoints" class="debug-button">重置标记点</button>
                </div>
                
                <div class="card">
                    <h2>魔方展开图</h2>
                    <div id="cubeLayout" class="cube-layout"></div>
                    <div class="button-container">
                    <button id="randomColors" class="debug-button">生成随机颜色</button>
                        <button id="getColors" class="debug-button">获取颜色</button>
                    </div>
                </div>
            </div>
            <div class="column">
                <div class="card">
                    <h2>实时视频流</h2>
                    <div class="video-container">
                        <img id="videoStream" src="" alt="实时视频流加载中...">
                        <canvas id="overlayCanvas"></canvas>
                        <div class="status-overlay" id="streamStatus">连接中...</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 初始配置
        const videoWidth = 320;
        const videoHeight = 240;
        const defaultPoints = [
            {x: 86, y: 59},  // 点1
            {x: 169, y: 27}, // 点2
            {x: 280, y: 62}, // 点3
            {x: 78, y: 185}, // 点4
            {x: 158, y: 218}, // 点5
            {x: 272, y: 203}  // 点6
        ];
        const layoutMapping = [
            [-1, -1, -1,  0,  1,  2, -1, -1, -1, -1, -1, -1],
            [-1, -1, -1,  3,  4,  5, -1, -1, -1, -1, -1, -1],
            [-1, -1, -1,  6,  7,  8, -1, -1, -1, -1, -1, -1],
            [36, 37, 38, 18, 19, 20,  9, 10, 11, 45, 46, 47],
            [39, 40, 41, 21, 22, 23, 12, 13, 14, 48, 49, 50],
            [42, 43, 44, 24, 25, 26, 15, 16, 17, 51, 52, 53],
            [-1, -1, -1, 27, 28, 29, -1, -1, -1, -1, -1, -1],
            [-1, -1, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1],
            [-1, -1, -1, 33, 34, 35, -1, -1, -1, -1, -1, -1]
        ];
        
        // 状态变量
        var gateway = `ws://${window.location.hostname}/ws`;
        var websocket;
        var isConnected = false;
        var videoStream = document.getElementById('videoStream');
        var streamStatus = document.getElementById('streamStatus');
        var streamUrl = `http://${window.location.hostname}:81/stream`;
        var retryCount = 0;
        var maxRetries = 5;
        var points = JSON.parse(JSON.stringify(defaultPoints)); // 深拷贝
        var overlayCanvas = document.getElementById('overlayCanvas');
        var ctx = overlayCanvas.getContext('2d');
        var isDragging = false;
        var dragIndex = -1;
        var scaleX = 1;
        var scaleY = 1;
        
        // 颜色数据 - 默认生成随机颜色
        var colorData = Array(54).fill().map(() => {
            return `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`;
        });
        
        window.addEventListener('load', onLoad);
        window.addEventListener('resize', resizeCanvas);
        
        // 初始化WebSocket
        function initWebSocket() {
            console.log('Trying to open a WebSocket connection...');
            try {
                websocket = new WebSocket(gateway);
                websocket.onopen = onOpen;
                websocket.onclose = onClose;
                websocket.onmessage = onMessage;
                websocket.onerror = onError;
            } catch (e) {
                console.error('WebSocket connection failed:', e);
                streamStatus.textContent = '连接失败，使用调试模式';
                setTimeout(initWebSocket, 5000);
            }
        }
        
        // 调整Canvas大小
        function resizeCanvas() {
            const container = overlayCanvas.parentElement;
            overlayCanvas.width = container.clientWidth;
            overlayCanvas.height = container.clientHeight;
            
            // 计算缩放比例
            scaleX = overlayCanvas.width / videoWidth;
            scaleY = overlayCanvas.height / videoHeight;
            
            drawOverlay();
        }
        
        // 绘制覆盖层（点和连线）
        function drawOverlay() {
            ctx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
            
            // 绘制连线
            ctx.strokeStyle = '#ff0000';
            ctx.lineWidth = 2;
            
            // 绘制行连线
            drawLine(0, 1);
            drawLine(1, 2);
            drawLine(3, 4);
            drawLine(4, 5);
            
            // 绘制列连线
            drawLine(0, 3);
            drawLine(1, 4);
            drawLine(2, 5);
            
            // 绘制点
            for (let i = 0; i < points.length; i++) {
                const x = points[i].x * scaleX;
                const y = points[i].y * scaleY;
                
                // 绘制点
                ctx.beginPath();
                ctx.arc(x, y, 10, 0, Math.PI * 2);
                ctx.fillStyle = i === dragIndex ? '#ffff00' : '#00ff00';
                ctx.fill();
                ctx.strokeStyle = '#000000';
                ctx.lineWidth = 2;
                ctx.stroke();
                
                // 绘制数字
                ctx.fillStyle = '#000000';
                ctx.font = 'bold 14px Arial';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText((i + 1).toString(), x, y);
            }
            
            // 更新坐标显示
            updateCoordinatesDisplay();
        }
        
        // 绘制两点之间的连线
        function drawLine(i, j) {
            ctx.beginPath();
            ctx.moveTo(points[i].x * scaleX, points[i].y * scaleY);
            ctx.lineTo(points[j].x * scaleX, points[j].y * scaleY);
            ctx.stroke();
        }
        
        // 更新坐标显示
        function updateCoordinatesDisplay() {
            const coords = points.map(p => `(${Math.round(p.x)},${Math.round(p.y)})`).join(', ');
            document.getElementById('coordinatesDisplay').textContent = coords;
        }
        
        // 发送坐标到服务器
        function sendCoordinates() {
            if (isConnected && websocket) {
                const coords = points.map(p => `(${Math.round(p.x)},${Math.round(p.y)})`).join(',');
                websocket.send('update_pos:' + coords);
            }
        }
        
        // 处理鼠标事件
        function initMouseEvents() {
            overlayCanvas.addEventListener('mousedown', handleMouseDown);
            overlayCanvas.addEventListener('mousemove', handleMouseMove);
            overlayCanvas.addEventListener('mouseup', handleMouseUp);
            overlayCanvas.addEventListener('mouseleave', handleMouseUp);
        }
        
        function handleMouseDown(e) {
            e.preventDefault(); // 阻止默认行为
            const rect = overlayCanvas.getBoundingClientRect();
            const x = (e.clientX - rect.left) / scaleX;
            const y = (e.clientY - rect.top) / scaleY;
            
            // 增加检测灵敏度
            for (let i = 0; i < points.length; i++) {
                const dx = points[i].x - x;
                const dy = points[i].y - y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                
                if (distance < 20) { // 增大检测半径到20像素
                    isDragging = true;
                    dragIndex = i;
                    overlayCanvas.style.cursor = 'grabbing';
                    drawOverlay();
                    break;
                }
            }
        }

        function handleMouseMove(e) {
            if (!isDragging) return;
            e.preventDefault(); // 阻止默认行为
            
            const rect = overlayCanvas.getBoundingClientRect();
            points[dragIndex].x = Math.max(0, Math.min(videoWidth, (e.clientX - rect.left) / scaleX));
            points[dragIndex].y = Math.max(0, Math.min(videoHeight, (e.clientY - rect.top) / scaleY));
            
            drawOverlay();
        }

        function handleMouseUp(e) {
            if (isDragging) {
                e.preventDefault(); // 阻止默认行为
                isDragging = false;
                overlayCanvas.style.cursor = 'default';
                sendCoordinates();
            }
        }
        
        // 初始化魔方展开图
        function initCubeLayout() {
            const container = document.getElementById('cubeLayout');
            container.innerHTML = '';
            
            for (let row = 0; row < layoutMapping.length; row++) {
                for (let col = 0; col < layoutMapping[row].length; col++) {
                    const cellValue = layoutMapping[row][col];
                    const cell = document.createElement('div');
                    cell.className = 'cube-cell';
                    
                    if (cellValue === -1) {
                        cell.classList.add('hidden');
                    } else {
                        cell.style.backgroundColor = colorData[cellValue];
                        const indexSpan = document.createElement('span');
                        indexSpan.className = 'index';
                        indexSpan.textContent = cellValue;
                        cell.appendChild(indexSpan);
                    }
                    
                    container.appendChild(cell);
                }
            }
        }
        
        // 生成随机颜色数据
        function generateRandomColors() {
            colorData = Array(54).fill().map(() => {
                return `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`;
            });
            initCubeLayout();
        }
        
        // 重置标记点位置
        function resetPoints() {
            points = JSON.parse(JSON.stringify(defaultPoints));
            drawOverlay();
            sendCoordinates();
        }
        
        // HSV转RGB函数
        function hsvToRgb(h, s) {
            // 固定亮度值 (255/255)
            const v = 1;
            // 饱和度转换为0-1范围
            const sat = s / 255;
            
            let r, g, b;
            const c = v * sat;
            const hPrime = (h * 2) / 60; // 转换为0-360范围
            const x = c * (1 - Math.abs((hPrime % 2) - 1));
            
            if (hPrime >= 0 && hPrime < 1) {
                [r, g, b] = [c, x, 0];
            } else if (hPrime >= 1 && hPrime < 2) {
                [r, g, b] = [x, c, 0];
            } else if (hPrime >= 2 && hPrime < 3) {
                [r, g, b] = [0, c, x];
            } else if (hPrime >= 3 && hPrime < 4) {
                [r, g, b] = [0, x, c];
            } else if (hPrime >= 4 && hPrime < 5) {
                [r, g, b] = [x, 0, c];
            } else {
                [r, g, b] = [c, 0, x];
            }
            
            const m = v - c;
            r = Math.round((r + m) * 255);
            g = Math.round((g + m) * 255);
            b = Math.round((b + m) * 255);
            
            return `rgb(${r}, ${g}, ${b})`;
        }
        
        // WebSocket事件处理
        function onOpen(event) {
            console.log('Connection opened');
            isConnected = true;
            streamStatus.textContent = '正在连接视频流...';
            streamStatus.classList.remove('hidden');
            
            // 连接建立后请求当前亮度
            websocket.send('get_brightness');
            // 请求当前坐标
            websocket.send('get_pos');
            
            // 启用控制功能
            document.getElementById('brightnessSlider').disabled = false;
            document.getElementById('button').disabled = false;
            
            // 启动视频流
            startVideoStream();
        }
        
        function startVideoStream() {
            videoStream.src = streamUrl;
            videoStream.onload = function() {
                streamStatus.textContent = '视频流已连接';
                streamStatus.classList.remove('hidden');
                retryCount = 0; // 重置重试计数
                
                // 5秒后隐藏状态提示
                setTimeout(() => {
                    streamStatus.classList.add('hidden');
                }, 5000);
            };
            
            videoStream.onerror = function() {
                streamStatus.textContent = '视频流连接失败';
                streamStatus.classList.remove('hidden');
                retryCount++;
                
                if(retryCount <= maxRetries) {
                    streamStatus.textContent += `，${3}秒后重试 (${retryCount}/${maxRetries})`;
                    setTimeout(startVideoStream, 3000);
                } else {
                    streamStatus.textContent = '视频流连接失败，请刷新页面重试';
                }
            };
        }
        
        function onClose(event) {
            console.log('Connection closed');
            isConnected = false;
            streamStatus.textContent = '连接已断开';
            streamStatus.classList.remove('hidden');
            
            // 禁用控制功能
            document.getElementById('brightnessSlider').disabled = true;
            document.getElementById('button').disabled = true;
            document.getElementById('brightnessValue').innerHTML = '--';
            
            setTimeout(initWebSocket, 2000);
        }
        
        function onError(event) {
            console.error('WebSocket error:', event);
            streamStatus.textContent = '连接错误';
            streamStatus.classList.remove('hidden');
        }
        
        function onMessage(event) {
            console.log('Received:', event.data);
            
            if(event.data.startsWith('brightness:')) {
                var brightness = event.data.split(':')[1];
                document.getElementById('brightnessValue').innerHTML = brightness;
                document.getElementById('brightnessSlider').value = brightness;
            }
            else if(event.data.startsWith('positions:')) {
                const coords = event.data.split(':')[1];
                const pointsData = coords.split('),(')
                    .map(str => str.replace(/[()]/g, ''))
                    .filter(str => str.includes(','))
                    .map(str => {
                        const [x, y] = str.split(',');
                        return {x: parseInt(x), y: parseInt(y)};
                    });
                
                if (pointsData.length === 6) {
                    points = pointsData;
                    drawOverlay();
                }
            }
            else if(event.data.startsWith('colors:')) {
                const colorStr = event.data.substring(7); // 去掉"colors:"
                const parts = colorStr.split(',');
                if (parts.length === 108) { // 54组，每组两个值
                    for (let i = 0; i < 54; i++) {
                        const h = parseInt(parts[i * 2]);
                        const s = parseInt(parts[i * 2 + 1]);
                        // 将HSV转换为RGB字符串
                        colorData[i] = hsvToRgb(h, s);
                    }
                    initCubeLayout();
                }
            }
        }
        
        function onLoad(event) {
            // 初始禁用控制功能
            document.getElementById('brightnessSlider').disabled = true;
            document.getElementById('button').disabled = true;
            
            // 初始化覆盖层
            resizeCanvas();
            drawOverlay();
            initMouseEvents();
            
            // 初始化魔方展开图
            initCubeLayout();
            
            // 初始化调试按钮
            document.getElementById('resetPoints').addEventListener('click', resetPoints);
            document.getElementById('randomColors').addEventListener('click', generateRandomColors);
            document.getElementById('getColors').addEventListener('click', function() {
                if(isConnected) websocket.send('get_colors');
            });
            
            // 尝试连接WebSocket
            initWebSocket();
            initButton();
            initSlider();
        }
        
        function initButton() {
            document.getElementById('button').addEventListener('click', function() {
                if(isConnected) {
                    websocket.send('toggle');
                    this.textContent = "还原中...";
                    this.disabled = true;
                    setTimeout(() => {
                        this.textContent = "开始还原";
                        this.disabled = false;
                    }, 5000);
                }
            });
        }
        
        function initSlider() {
            document.getElementById('brightnessSlider').addEventListener('input', function() {
                if(isConnected) websocket.send('brightness:' + this.value);
            });
        }
    </script>
</body>

</html>